﻿using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using User.Api.BizExtensions;
using User.Api.Dto.Card;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace User.Api.Controllers
{
    public class AddressController : ApiController
    {
        private static readonly object CardNoLocker = new object();
        private static readonly ILog Logger = LogManager.GetLogger(typeof(CardController));
        private GdsfybjyWeiXinEntities _ctx;

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            _ctx = new GdsfybjyWeiXinEntities();
            base.Initialize(controllerContext);
        }

        protected override void Dispose(bool disposing)
        {
            _ctx.Dispose();
            base.Dispose(disposing);
        }

        /// <summary>
        /// 获取用户的所有配送地址
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetAllAddress")]
        public GetAllResponse GetAll()
        {
            var azUser = AzUser.GetInApi(Request);
            
            //之前的查询会发生死锁，优化查询为NoLock
            var dbCards = (_ctx.Addresses.Where(x => x.WxUserId == azUser.UserId && x.Status == 1)
                .OrderByDescending(x => x.IsDefault).ThenBy(x => x.CardNo)
                .Select(x => new 
                {
                    Id = x.Id,
                    x.CardNo,
                    x.Phone,
                    x.CardName,
                    x.Address1,
                    x.IsDefault
                })).ToListReadUncommitted();

            var cards = dbCards.Select(x => new GetAllResponse.Card
            {
                Id = x.Id,
                Num = x.CardNo,
                Name = x.CardName,
                Address= x.Address1,
                Phone=x.Phone,
                IsDefault = x.IsDefault == 1
            }).ToList();

            return new GetAllResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                Cards = cards
            };
        }

        /// <summary>
        /// 设置默认就诊卡
        /// </summary>
        /// <param name="id">就诊卡id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("SetDefault")]
        public SetDefaultResponse SetDefault(int id)
        {
            var azUser = AzUser.GetInApi(Request);
            var cards = _ctx.Addresses.Where(x => x.WxUserId == azUser.UserId).ToList();
            foreach (var card in cards)
            {
                card.IsDefault = 0;
                if (card.Id == id)
                {
                    card.IsDefault = 1;
                }
            }
            _ctx.SaveChanges();

            return new SetDefaultResponse { ResultCode = "0", ResultMsg = "" };
        }

        /// <summary>
        /// 删除就诊卡
        /// </summary>
        /// <param name="id">就诊卡id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("Delete")]
        public DeleteResponse Delete(int id)
        {
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.Addresses.FirstOrDefault(x => x.Id == id && x.WxUserId == azUser.UserId);
            if (card != null)
            {
                card.Status = 0;
                card.DeleteDt = DateTime.Now;
                _ctx.SaveChanges();

                // 如果删除了默认卡，则自动设置其余卡号小的卡为默认就诊卡
                if (card.IsDefault == 1)
                {
                    var cards = _ctx.Addresses.Where(x => x.Status == 0 && x.WxUserId == azUser.UserId)
                        .OrderBy(x => x.CardNo).ToList();
                    for (int i = 0; i < cards.Count; i++)
                    {
                        cards[i].IsDefault = i == 0 ? 1 : 0;
                    }
                    _ctx.SaveChanges();
                }
            }

            return new DeleteResponse { ResultCode = "0", ResultMsg = "" };
        }

        /// <summary>
        /// 新建地址
        /// </summary>
        /// <param name="isDefault">是否设置为默认就诊卡</param>
        /// <param name="type">卡类型</param>
        /// <param name="num">卡号</param>
        /// <param name="name">姓名</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("CreateAddress")]
        public AddNewResponse CreateAddress(bool isDefault, string num, string name, string phone, 
            string province, string city, string county, string address, string shipperCode)
        {
            var azUser = AzUser.GetInApi(Request);
            var cardMax = ConfigurationManager.AppSettings["CardMax"].ToInt32();
            var cardCount = _ctx.Addresses
                .Count(x => x.WxUserId == azUser.UserId && x.Status == 1);
            if (cardCount >= cardMax)
            {
                return new AddNewResponse
                {
                    ResultCode = "1",
                    ResultMsg = "最多可以添加" + cardMax + "张就诊卡!"
                };
            }

            if (cardCount == 0)
            {
                isDefault = true;
            }

            var newCard = new Address
            {
                WxUserId = azUser.UserId,
                CardNo = num.Trim(),
                CardName = name,
                Status = 1,
                CreateDt = DateTime.Now,
                UpdateDt = DateTime.Now,
                Phone = phone,
                Province = province,
                City = city,
                County = county,
                Address1 = address,
                ShipperCode = shipperCode,
            };
            _ctx.Addresses.Add(newCard);
            _ctx.SaveChanges();
            if (isDefault)
            {
                SetDefault(newCard.Id);
            }
            return new AddNewResponse
            {
                ResultCode = "0",
                ResultMsg = "",
            };
        }

        /// <summary>
        /// 以5天头，10位卡号
        /// </summary>
        /// <returns></returns>
        public string GenerateNewCardNo()
        {
            var cardNo = "";
            lock (CardNoLocker)
            {

                var maxSeed = 0;
                var usedCard = _ctx.UsedCards.OrderByDescending(x => x.Seed).FirstOrDefault();
                if (usedCard != null)
                {
                    maxSeed = usedCard.Seed;
                }
                maxSeed += 1;
                cardNo = (3000000000 + maxSeed).ToString();

                var model = new UsedCard();
                model.CardNo = cardNo;
                model.Seed = maxSeed;
                model.RecStatus = 0;
                model.RecCreateDt = DateTime.Now;
                _ctx.UsedCards.Add(model);

                _ctx.SaveChanges();
            }
            return cardNo;
        }
    }
}
